// void, Obj This, point pt
Unit this;
Unit u;

Sleep(rand(100)+30);
this = This.AsUnit();

if (.IsValid) {// leave parry mode at new command
	.SetParryMode(false);
	
	if(.hero.IsValid){
		if(.hero.HasItem("irage_battle")){
			Sleep(rand(200)+50);
			.AddCommand(true, "engage");
			return;
		} else if(.hero.HasItem("irage_battle_stand")){
			Sleep(rand(200)+50);
			.AddCommand(true, "stand_position");
			return;
		}
	}
	
	if(.item_count > 0){
		Item item;
		
		item = .FindItem("Terrain bonus I");
		if(item.IsValid)
			.RemoveItemsOfType("Terrain bonus I");
		else {
			item = .FindItem("Terrain bonus II");
			if(item.IsValid)
				.RemoveItemsOfType("Terrain bonus II");
			else {
				item = .FindItem("Terrain bonus III");
				if(item.IsValid)
					.RemoveItemsOfType("Terrain bonus III");
				else {
					item = .FindItem("Terrain bonus IV");
					if(item.IsValid)
						.RemoveItemsOfType("Terrain bonus IV");
				}
			}
		}
	}
}
	
if(!.InHolder)
	.AddCommand(false, "patrol", .pos);
	
while(1) {
	//.pr("Unit::patrol::going");
	u = .BestTargetInSquadSight();
	if(u.IsAlive() && .IsValidTarget(u))
	{
		Sleep(rand(200)+100);
		.AddCommand(true, "patrol", pt);
		.AddCommand(true, "engage");
		return;
	}
	else
	{
		if(.Goto (pt, 0, 1500, true, -1)) {
			Sleep(500);  // Else when Goto returns immediately there's an infinite loop of patrol commands (the software dies)
			break;
		}
		if(.TimeWithoutWalking() > 0) {
			Sleep(500);
			break;
		}
	}
}
//.pr("Unit::patrol: reached");
